package gv.project 
{
	import net.eriksjodin.arduino.Arduino;
	import net.eriksjodin.arduino.events.ArduinoEvent;

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.text.TextField;
	import flash.utils.Timer;
	import flash.utils.getTimer;

	/**
	 * @author rick
	 */
	public class ArduinoEventHandler extends Sprite 
	{
		private var ringPinData : Array = new Array();
		private var knopPinData : Array = new Array();
		private var arduinoRing : Arduino;
		private var arduinoKnop : Arduino;
		private var step : int = 4;
		private var ringTimer : Timer;
		public var tf : TextField;
		private var ringEventArray : Array = new Array();
		private var knopEventData : Array = new Array();
		private static const KNOP_RESPONSE : int = 500;

		public function ArduinoEventHandler()	
		{
			trace("GO");
			tf = new TextField();
			tf.width = 300;
			tf.height = 300;
			addChild(tf);
			tf.text = "init";
			init();
		}

		private	function init() : void
		{
			arduinoRing = new Arduino("127.0.0.1", 5331);
			arduinoKnop = new Arduino("127.0.0.1", 5332);
			tracer("bla");
			arduinoRing.addEventListener(ArduinoEvent.FIRMWARE_VERSION, onArduinoStartupRing);
			arduinoKnop.addEventListener(ArduinoEvent.FIRMWARE_VERSION, onArduinoStartupKnop);
		}

		private function tracer(string : String) : void
		{
			tf.appendText("\n" + string);
			trace(string);
			tf.scrollV = tf.bottomScrollV + 5;
		}

		private function onArduinoStartupKnop(event : ArduinoEvent) : void
		{
			arduinoKnop.removeEventListener(ArduinoEvent.FIRMWARE_VERSION, onArduinoStartupKnop);
			trace("KNOP ARDUINO STARTED"); 
			
			for(var pin : int = 2;pin <= 12; pin++)
			{
				arduinoKnop.setPinMode(pin, Arduino.INPUT);
			}
			arduinoKnop.enableDigitalPinReporting();
			arduinoKnop.addEventListener(ArduinoEvent.DIGITAL_DATA, arduinoLoop);
		}

		private function onArduinoStartupRing(e : ArduinoEvent) : void 
		{
			arduinoRing.removeEventListener(ArduinoEvent.FIRMWARE_VERSION, onArduinoStartupRing);
			trace("RING ARDUINO STARTED"); 
			
			for(var pin : int = 2;pin <= 12; pin++)
			{
				
				arduinoRing.setPinMode(pin, Arduino.OUTPUT);
				arduinoRing.writeDigitalPin(pin, Arduino.LOW);
			}
			arduinoRing.setAnalogPinReporting(0, Arduino.ON);
			ringTimer = new Timer(20);
			ringTimer.addEventListener(TimerEvent.TIMER, ringStep);
			ringTimer.start();
		}

		private function ringStep(event : TimerEvent) : void
		{
			var pin : int = Math.ceil(step / 3);
			if(step % 3 == 1)
			{
				//trace("high: " + pin);
				arduinoRing.writeDigitalPin(pin, Arduino.HIGH);
			}
			if(step % 3 == 2)
			{
				var ret : Number = arduinoRing.getAnalogData(0);
				//tracer("read: " + pin + " - " + ret);
				ringPinData[pin] = ret;
			}
			if(step % 3 == 0)
			{
				//trace("low: " + pin);
				arduinoRing.writeDigitalPin(pin, Arduino.LOW);						
			}
			
			step++;
			
			if(Math.ceil(step / 3) == 13)
			{
				step = 4;
			}
			fireRingEvents();
		}

		private function arduinoLoop(event : Event) : void 
		{
			for(var pin : int = 2;pin <= 12; pin++)
			{
				
				knopPinData[pin] = arduinoKnop.getDigitalData(pin);
			}
			fireKnopEvents();
		}

		private function fireKnopEvents() : void
		{
			for(var pin : int = 2;pin <= 12; pin++)
			{
				if(knopEventData[pin] == null)
				{
					knopEventData[pin] = new KnopData();
				}
				var prevKnopEvent:KnopData = knopEventData[pin] as KnopData;
				if(knopPinData[pin] == 0)
				{
					if(prevKnopEvent.time + KNOP_RESPONSE < getTimer())
					{
						prevKnopEvent.time = getTimer();
						dispatchEvent(new KnopEvent(KnopEvent.BUTTON_DOWN, pin));
						trace("event dispatched: knop down op pin [ " + pin + " ]");
					}
				}
			}
		}

		private function fireRingEvents() : void
		{
			for(var pin : int = 2;pin <= 12; pin++)
			{
				if(ringEventArray[pin] == null)
				{
					ringEventArray[pin] = new RingData();	
				}
				var prevRingData : RingData = ringEventArray[pin] as RingData;
				if(ringPinData[pin] > 50)
				{
					//if ring turned off -> turn on
					var d : int = ringPinData[pin];
					var ring : int;
					if(d > 50 && d <= 300)
					{
						ring = 1;
					}
					if(d > 300 && d <= 700)
					{
						ring = 2;
					}
					if(d > 700)
					{
						ring = 3;
					}
					if(d > 900)
					{
						ring = 4; // RING 4 = ERROR! Ring ligt niet goed op de knop.
					}
					if(prevRingData.state == RingData.OFF)
					{
						prevRingData.time = getTimer();
						prevRingData.state = RingData.ON;
						prevRingData.ring = ring;
						dispatchEvent(new RingEvent(RingEvent.RING_ON, pin, ring));
						trace("event dispatched: ring [ " + ring + " ]  OP pin [ " + pin + " ]");
					}
				}
				else
				{
					//if ring turned on, turn off
					if(prevRingData.state == RingData.ON)
					{
						prevRingData.time = getTimer();
						prevRingData.state = RingData.OFF;
						prevRingData.ring = 0;
						dispatchEvent(new RingEvent(RingEvent.RING_OFF, pin, ring));
						trace("event dispatched: ring [ " + ring + " ]  VAN pin [ " + pin + " ]");		 
					}
				}
			}
		}
	} 
}

